package frame.options.simulation.results.virtualNetworks.numerical;

import java.util.Iterator;
import java.util.Map.Entry;

import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import model.components.links.link.BandwidthBackupFlag;
import model.components.links.link.PhysicalLink;
import model.components.links.link.VirtualLink;
import model.components.networks.network.VirtualNetwork;
import model.components.nodes.node.VirtualNode;
import model.components.nodes.node.VirtualServer;

@SuppressWarnings("serial")
public class VirtualNetworkTable1 extends JTable
{
	private VirtualNetwork virtualNetwork;
	public VirtualNetwork getVirtualNetwork(){ return virtualNetwork; }
	public void setVirtualNetwork( VirtualNetwork virtualNetwork ){ this.virtualNetwork = virtualNetwork; }
	
	public VirtualNetworkTable1( VirtualNetwork virtualNetwork )
	{
		this.setVirtualNetwork( virtualNetwork );
		
		this.setModel( this.defaultTableModel() );
		this.setEnabled( false );
	}
	
	private DefaultTableModel defaultTableModel()
	{
		int leasedCPU = 0;
		int leasedMemory = 0;
		int leasedDiskSpace = 0;
		
		int cpuCost = 0;
		int memoryCost = 0;
		int diskSpaceCost = 0;
		
		for( VirtualNode virtualNode: this.getVirtualNetwork().getVirtualNodes() )
		{
			int virtualNodeCpu = 0;
			int virtualNodeMemory = 0;
			int virtualNodeDiskSpace = 0;
			
			if( virtualNode.getPhysicalNode() != null )
			{
				virtualNodeCpu = virtualNode.getCpu();
				virtualNodeMemory = virtualNode.getMemory();
				virtualNodeDiskSpace = virtualNode.getDiskSpace();;
			}
			
			leasedCPU += virtualNodeCpu;
			leasedMemory += virtualNodeMemory;
			leasedDiskSpace += virtualNodeDiskSpace;
			
			cpuCost += virtualNodeCpu * virtualNode.getCpuUnitTimeUnitPrice() * virtualNode.getLifeTime();
			memoryCost += virtualNodeMemory * virtualNode.getMemoryUnitTimeUnitPrice() * virtualNode.getLifeTime();
			
			if( virtualNode.getType().equals( VirtualNode.SERVER_TYPE ) )
				diskSpaceCost += virtualNodeDiskSpace * ( (VirtualServer) virtualNode ).getDiskSpaceUnitTimeUnitPrice() * virtualNode.getLifeTime();
		}
		
		int leasedBandwidth = 0;
		int bandwidthCost = 0;
		
		for( VirtualLink virtualLink: this.getVirtualNetwork().getVirtualLinks() )
		{
			Iterator< Entry< PhysicalLink, BandwidthBackupFlag > > iterator = virtualLink.getPhysicalLinksBandwidthsBackupFlags().entrySet().iterator();
			
			while( iterator.hasNext() )
			{
				int bandwidth = iterator.next().getValue().getBandwidth();
				leasedBandwidth += bandwidth;
				bandwidthCost += bandwidth * virtualLink.getBandwidthUnitTimeUnitPrice() * virtualLink.getLifeTime();
			}
		}
		
		int networkCost = cpuCost + memoryCost + diskSpaceCost + bandwidthCost;
		this.getVirtualNetwork().setNetworkCost( networkCost );

		DefaultTableModel defaultTableModel = new DefaultTableModel( new String[]{ "<html><b>Resource</b></html>", "<html><b>Leased</b></html>", "<html><b>Cost</b></html>" }, 0 );
		defaultTableModel.addRow( new Object[]{ "<html><b>CPU</b></html>", leasedCPU, cpuCost } );
		defaultTableModel.addRow( new Object[]{ "<html><b>Memory</b></html>", leasedMemory, memoryCost } );
		defaultTableModel.addRow( new Object[]{ "<html><b>Disk Space</b></html>", leasedDiskSpace, diskSpaceCost } );
		defaultTableModel.addRow( new Object[]{ "<html><b>Bandwidth</b></html>", leasedBandwidth, bandwidthCost } );
		defaultTableModel.addRow( new Object[]{ "<html><b>Total</b></html>", "", "<html><b>" + networkCost + "</b></html>" } );

		return defaultTableModel;
	}
	
}
